Blog System | Note-2

Blog System | Note-2

@2018年7月29日 14:38:38 Knowledge From Imooc

数据持久化

JPA

​ 用于管理Java EE和Java SE环境中的持久化,以及对象/关系(O/R)映射的Java API;

实体@Entity

​ 表示数据库中的表,每个实体实体对应于表中的行;

​ 类必须有一个public或protected的无参构造函数;

​ 实体实例被当作值以分离对象方式进行传递,则该类必须实现Serializable接口;

​ 唯一的标识:主键或复合主键;

关系 Relation

​ 一对一:@OneToOne

​ 一对多:@OneToMany

​ 多对一:@ManyToOne

​ 多对多:@ManyToMany

管理实体的接口 EntityManager

​ 定义用于持久性上下文进行交互的方法;

​ 创建和删除持久实体实例,通过实体的主键查找实体;

​ 允许在实体上运行查询;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 获取EntityManager实例
@PersistenceUnit // 持久化单元
EntityManagerFactory emf;
EntityManager em;
@Resource
UserTransaction utx;
...
em = emf.createEntityManager();
try{
utx.begin();
em.persist(SomeEntity);
em.merge(AnotherEntity);
em.remove(ThirdEntity);
utx.commit();
}catch(Exception e){
utx.rollback();
}
1
2
3
4
5
6
7
8
// 查找实体
@PersistenceContext
EntityManager em;
public void enterOrder(int custID,CustomerOrder newOrder){
Customer cust = em.find(Customer,custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
Spring Data JPA

​ 更大的Spring Data家族的一部分;

​ 对基于JPA的数据访问层的增强支持;

​ 更容易构建基于Spring数据访问技术栈的程序;

常用接口

​ CrudRepository

​ PagingAndSortingRepository

​ 自定义接口:根据方法名创建查询 public interface UserRepository extends Repository<User,Long>{}

应用@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Entity
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
// Controller
findAll();
findOne();
delete();
save();
// application.properties
# 使用H2控制台:
spring.h2.console.enabled=true
#查看
localhost:8080/h2-console
// application.properties
# DataSource
spring.datasource.url=...
spring.datasource.username=...
spring.datasource.password=...
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop

全文搜索

全文搜索

​ 概念:将文件中所有文本与搜索项匹配的文字资料检索方法

​ Knowledge About(数据结构 && 非结构化数据的检索)

​ 实现原理:建立文本库、建立索引、执行搜索、过滤结果

​ 实现技术:Lucene、ElasticSearch(ES)、Solr

ElasticSearch

​ 高度可扩展的开源全文搜索和分析引擎;

​ 快速的、近实时性的对大数据进行存储、搜索和分析;

​ 用于支持有复杂的数据搜索需求的企业级应用;

特点:分布式(分布到多个分片上)、高可用(由分布式所得)、多类型(多种数据类型)、多API、面向文档(不需要事先定义模式)、异步写入(性能高于同步)、近实时、基于Lucene、Apache协议

核心概念:

近实时:

​ 搜索文档到可搜索之间的时间,轻微的延时,1s左右;

​ 每隔n秒刷新数据;

​ 索引建立后,不会直接写入磁盘,存在文件系统缓存中,根据刷新策略,定期同步到磁盘中;

集群:

​ 一个或多个节点的集合,保存应用的全部数据, 并提供基于全部节点的集成式的索引和搜索功能;

​ 每个集群有唯一名称;

节点:

​ 集群中的一台服务器,用于保存数据,并且参与整个集群的索引和搜索;

索引(5个分片,1个副本):

​ 加快搜索速度,相似文档的集合;

​ 在单个集群中,根据需要,定义任意数量的索引;

类型:

​ 对一个索引中的文档中,做进一步的细分,根据公共属性划分;

文档:

​ 进行索引的基本单位,JSON格式;

分片:

​ 超出单个节点处理的范围,将索引分成多个分片(含副本),存储索引的部分数据;

副本:

​ 分片的故障不可避免,为了可靠性,设置分片副本,分配到不同节点上;

​ 增加吞吐量,分配到不同副本中;

应用@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// build.gradle

// 添加 Spring Daat Elasticsearch 的依赖
compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
// 添加 JNA 的依赖
compile('net.java.dev.jna:jna:4.3.0')

// application.properties
# Elasticsearch 服务地址
spring.data.elasticsearch.cluster-nodes=localhost:9300
# 设置连接超时时间
spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

// domain
@Document(indexName="blog",type="blog")

// repository
public interface EsBlogRepository extends ElasticsearchRepository<EsBlog,String> {...}

进行controller之前,需要启动elasticsearch服务器
PS:注意jar包的版本,以及elasticsearch服务器的版本问题

// controller
@GetMapping
public List<EsBlog> list(@RequestParam(value = "title")String title,
@RequestParam(value = "summary")String summary,
@RequestParam(value = "content")String content,
@RequestParam(value = "pageIndex",defaultValue = "0")int pageIndex,
@RequestParam(value = "pageSize",defaultValue = "10")int pageSize){
// 数据在测试用例中初始化
Pageable pageable = new PageRequest(pageIndex, pageSize);
Page<EsBlog> page = esBlogRepository.find...(title,summary,content,pageable);
return page.getContent();
}

附录

数据结构

​ 结构化:具有固定格式或有限长度的数据(数据库、元数据)

​ 非结构化:不定长或无固定格式的数据(邮件,word文档)

非结构化数据的检索

​ 顺序扫描 Serial Scanning : 从头到尾搜索

​ 全文搜索 Full-text Search : 将非结构化数据部分信息,组织成结构化数据,添加索引,进行搜索

2018年7月29日 22:35:47